package com.sqlist.share;

import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.LatLngBounds;
import com.baidu.mapapi.utils.DistanceUtil;
import com.sqlist.share.connection.Client;
import com.sqlist.share.dto.LinkDTO;
import com.sqlist.share.dto.LocationDTO;
import com.sqlist.share.dto.MessageDTO;
import com.sqlist.share.util.Callback;
import com.sqlist.share.util.Const;
import com.sqlist.share.util.GsonUtils;
import com.sqlist.share.util.HttpUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "Share - MainActivity";

    private DrawerLayout drawerLayout;
    private FloatingActionButton locationBtn;
    private Button logoutBtn;
    private TextView userNameTextView;
    private ListView leftMenuListView;
    private FloatingActionButton openLeftMenuBtn;

    private SharedPreferences sharedPreferences;
    private SharedPreferences.Editor editor;

    private static Handler handler;

    public static Handler getHandler() {
        return handler;
    }

    private Intent intent;

    private MapView mMapView = null;
    private BaiduMap mBaiduMap = null;
    private LocationClient mLocationClient = null;
    private LatLng myLatLng;
    private boolean firstLoca = true;
    private boolean firstIn = true;

    private void setStatusBar() {
        // 禁止横屏
//        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        // 去掉Android原生的标题栏
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);

        // 将状态栏设成透明
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = this.getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
            window.setNavigationBarColor(Color.TRANSPARENT);
        }

        // android6.0以后可以对状态栏文字颜色和图标进行修改
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 在使用SDK各组件之前初始化context信息，传入ApplicationContext
        // 注意该方法要再setContentView方法之前实现
        SDKInitializer.initialize(getApplicationContext());

        setStatusBar();

        setContentView(R.layout.activity_main);
        Log.i(TAG, "onCreate()");

        init();

        startNettyService();
    }

    private void init() {
        Log.i(TAG, "初始化按钮");
        drawerLayout = findViewById(R.id.drawer_layout);
        mMapView = findViewById(R.id.bmapView);
        locationBtn = findViewById(R.id.locationBtn);
        openLeftMenuBtn = findViewById(R.id.openLeftMenuBtn);
        logoutBtn = findViewById(R.id.logoutBtn);
        userNameTextView = findViewById(R.id.userNameTextView);
        leftMenuListView = findViewById(R.id.leftMenuListView);

        sharedPreferences = getSharedPreferences("usernameAndToken", MODE_PRIVATE);
        editor = sharedPreferences.edit();

        Log.i(TAG, "设置用户名");
        userNameTextView.setText(Const.USERNAME);

        openLeftMenuBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                drawerLayout.openDrawer(Gravity.START);
            }
        });

        locationBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG, "移动到自己的位置");
                MapStatus.Builder builder = new MapStatus.Builder();
                builder.target(myLatLng).zoom(18.0f);
                mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
            }
        });

        logoutBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG, "退出登录");

                Map<String, String> map = new HashMap<>();
                map.put("username", Const.USERNAME);
                map.put("token", Const.TOKEN);

                HttpUtils.getInstance().post("http://" + Const.HOST + ":" + Const.HTTP_PORT + "/logout", map, new Callback() {
                    @Override
                    public void onSuccess(Object o) {
                        Log.i(TAG, "退出成功");
                        Toast.makeText(MainActivity.this, "退出成功", Toast.LENGTH_LONG).show();

                        Log.i(TAG, "清除 username 和 token");
                        editor.clear();
                        editor.commit();

                        Log.i(TAG, "关闭连接");
                        Client.getInstance().disConnect();

                        Intent serviceIntent = new Intent(MainActivity.this, NettyService.class);
                        stopService(serviceIntent);

                        Log.i(TAG, "跳转");
                        Intent intent = new Intent(MainActivity.this, LoginActivity.class);
                        startActivity(intent);
                        finish();
                    }

                    @Override
                    public void onFailed(Exception e) {

                    }
                }, MessageDTO.class);
            }
        });

        mMapView = findViewById(R.id.bmapView);
        mBaiduMap = mMapView.getMap();

        mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                // 获取传递的 bundle
                Bundle bundle = marker.getExtraInfo();
                String username = bundle.getString("username");

                LatLng latLng = marker.getPosition();
                double distance = DistanceUtil.getDistance(myLatLng, latLng);
                String distanceString = String.format("%.2f", distance);

                TextView textView = new TextView(getApplicationContext());
                textView.setText(username + "\n相距" + distanceString + "米");
                textView.setGravity(Gravity.CENTER);
                textView.setBackgroundResource(R.color.background);
                textView.setPadding(10, 5, 10, 5);

                InfoWindow mInfoWindow = new InfoWindow(textView, marker.getPosition(), -100);
                mBaiduMap.showInfoWindow(mInfoWindow);
                return false;
            }
        });

        handler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                if (msg.what == LinkDTO.LINK_FAIL) {
                    Log.i(TAG, "Token过期");
                    Toast.makeText(MainActivity.this, "Token过期，需重新登录", Toast.LENGTH_LONG).show();

                    Log.i(TAG, "清空 usernameAndToken 的内容");
                    editor.clear();
                    editor.commit();

                    Intent intent = new Intent(MainActivity.this, LoginActivity.class);
                    startActivity(intent);
                } else if (msg.what == LinkDTO.LINK_SUCCESS) {
                    Log.i(TAG, "登录成功");

                    Log.i(TAG, "定位");
                    locate();
                } else if (msg.what == LocationDTO.LOCATION) {
                    Log.i(TAG, "获取他人定位信息，并画在地图上");
                    Bundle bundle = msg.getData();
                    Map<String, LocationDTO> map = (Map<String, LocationDTO>) bundle.get("locationMap");
                    addOverlay(map);
                } else if (msg.what == LinkDTO.LINK_ERROR) {
                    Log.i(TAG, "连接错误");
                    Toast.makeText(MainActivity.this, "连接错误，重新登录", Toast.LENGTH_LONG).show();

                    Client.getInstance().disConnect();

                    Intent serviceIntent = new Intent(MainActivity.this, NettyService.class);
                    stopService(serviceIntent);

                    Intent intent = new Intent(MainActivity.this, LoginActivity.class);
                    startActivity(intent);
                    finish();
                }
                return false;
            }
        });
    }

    public void addOverlay(Map<String, LocationDTO> map) {
        Log.i(TAG, "清除之前画的点");
        mBaiduMap.clear();

        List<LatLng> latList = new ArrayList<>();
        List<OverlayOptions> optionsList = new ArrayList<>();

        for (Map.Entry<String, LocationDTO> entry : map.entrySet()) {
            String username = entry.getKey();
            if (!Const.USERNAME.equals(username)) {
                LocationDTO locationDTO = entry.getValue();

                LatLng point = new LatLng(locationDTO.getLatitude(), locationDTO.getLongitude());
                latList.add(point);
                BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.icon);

                // 给marker的信息
                Bundle bundle = new Bundle();
                bundle.putString("username", username);

                OverlayOptions options = new MarkerOptions().position(point).icon(icon).extraInfo(bundle);
                optionsList.add(options);
            }
        }

        Log.i(TAG, "批量添加点");
        mBaiduMap.addOverlays(optionsList);

        if (firstIn) {
            Log.i(TAG, "显示所有点在屏幕内");
            firstIn = false;
            // 显示所有点在屏幕内
            LatLngBounds.Builder builder = new LatLngBounds.Builder();
            for (int i = 0; i < latList.size(); i++) {
                builder.include(latList.get(i));
            }
            builder.include(myLatLng);
            //更新地图
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngBounds(builder.build()));
        }
    }

    public void locate() {
        //开启定位图层
        mBaiduMap.setMyLocationEnabled(true);
        //声明LocationClient类
        mLocationClient = new LocationClient(getApplicationContext());

        //配置定位SDK参数
        initLocation();
        mLocationClient.registerLocationListener(new MyLocationListener());
        mLocationClient.start();
        mLocationClient.requestLocation();
    }

    private void initLocation() {
        LocationClientOption locationClientOption = new LocationClientOption();
        //可选，默认高精度，
        //设置定位模式，高精度，低功耗，仅设备
        locationClientOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选，设置返回经纬度坐标类型，默认gcj02
        locationClientOption.setCoorType("bd09ll");
        //可选，设置发起定位请求的间隔，int类型，单位ms
        //如果设置为0，则代表单次定位，即仅定位一次，默认为0
        //如果设置非0，需设置1000ms以上才有效
        locationClientOption.setScanSpan(30000);
        //可选，设置是否使用gps，默认false
        //使用高精度和仅用设备两种定位模式的，参数必须设置为true
        locationClientOption.setOpenGps(true);
        //可选，设置是否当GPS有效时按照1S/1次频率输出GPS结果，默认false
        locationClientOption.setLocationNotify(true);
        //可选，定位SDK内部是一个service，并放到了独立进程。
        //设置是否在stop的时候杀死这个进程，默认（建议）不杀死，即setIgnoreKillProcess(true)
        locationClientOption.setIgnoreKillProcess(false);
        //可选，设置是否收集Crash信息，默认收集，即参数为false
        locationClientOption.setIgnoreKillProcess(false);
        //可选，7.2版本新增能力
        //如果设置了该接口，首次启动定位时，会先判断当前WiFi是否超出有效期，若超出有效期，会先重新扫描WiFi，然后定位
        locationClientOption.setWifiCacheTimeOut(5 * 60 * 1000);
        //可选，设置是否需要过滤GPS仿真结果，默认需要，即参数为false
        locationClientOption.setEnableSimulateGps(false);
        //mLocationClient为第二步初始化过的LocationClient对象
        //需将配置好的LocationClientOption对象，通过setLocOption方法传递给LocationClient对象使用
        //更多LocationClientOption的配置，请参照类参考中LocationClientOption类的详细说明
        mLocationClient.setLocOption(locationClientOption);
    }

    //实现BDLocationListener接口,BDLocationListener为结果监听接口，异步获取定位结果
    public class MyLocationListener extends BDAbstractLocationListener {

        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            Log.i(TAG, "接收位置信息 (" + bdLocation.getLatitude() + ", " + bdLocation.getLongitude() + ")");
            myLatLng = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
            //构造定位数据
            MyLocationData locationData = new MyLocationData.Builder()
                    .accuracy(bdLocation.getRadius())
                    //此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(100).latitude(bdLocation.getLatitude())
                    .longitude(bdLocation.getLongitude()).build();
            //设置定位数据
            mBaiduMap.setMyLocationData(locationData);

            Log.i(TAG, "发送定位信息");
            LocationDTO locationDTO = new LocationDTO(bdLocation.getLatitude(), bdLocation.getLongitude());
            MessageDTO<LocationDTO> locationDTOMessageDTO = new MessageDTO<>();
            locationDTOMessageDTO.setCode(Const.REQUEST);
            locationDTOMessageDTO.setType("locationDTO");
            locationDTOMessageDTO.setUsername(Const.USERNAME);
            locationDTOMessageDTO.setToken(Const.TOKEN);
            locationDTOMessageDTO.setMsg("定位信息");
            locationDTOMessageDTO.setData(locationDTO);
            Client.getInstance().sendMessageDTO(GsonUtils.getInstance().toJson(locationDTOMessageDTO));

            MyLocationConfiguration configuration =
                    new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, null);
            mBaiduMap.setMyLocationConfiguration(configuration);
            //当不需要定位图层时，关闭定位图层
//            mBaiduMap.setMyLocationEnabled(false);
            if (firstLoca) {
                firstLoca = false;
                MapStatus.Builder builder = new MapStatus.Builder();
                builder.target(myLatLng).zoom(18.0f);
                mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

                if (bdLocation.getLocType() == BDLocation.TypeGpsLocation) {
                    //GPS定位结果
                    Log.d(TAG, "GPS定位");
//                    Toast.makeText(MainActivity.this, bdLocation.getAddress().toString(), Toast.LENGTH_SHORT).show();
                } else if (bdLocation.getLocType() == BDLocation.TypeNetWorkLocation) {
                    //网络定位结果
                    Log.d(TAG, "网络定位");
//                    Toast.makeText(MainActivity.this, bdLocation.getAddress().toString(), Toast.LENGTH_SHORT).show();
                } else if (bdLocation.getLocType() == BDLocation.TypeOffLineLocation) {
                    //离线定位结果
                    Log.d(TAG, "离线定位");
//                    Toast.makeText(MainActivity.this, bdLocation.getAddress().toString(), Toast.LENGTH_SHORT).show();
                } else if (bdLocation.getLocType() == BDLocation.TypeServerError) {
                    Toast.makeText(MainActivity.this, "服务器错误，请检查", Toast.LENGTH_SHORT).show();
                } else if (bdLocation.getLocType() == BDLocation.TypeNetWorkException) {
                    Toast.makeText(MainActivity.this, "网络错误，请检查", Toast.LENGTH_SHORT).show();
                } else if (bdLocation.getLocType() == BDLocation.TypeCriteriaException) {
                    Toast.makeText(MainActivity.this, "手机模式错误，请检查是否飞行", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    public void startNettyService() {
        Log.i(TAG, "启动Netty的Service");

        intent = new Intent(MainActivity.this, NettyService.class);
        startService(intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy");
        //在activity执行onDestroy时执行mMapView.onDestroy()，实现地图生命周期管理
        mMapView.onDestroy();

        stopService(intent);
    }

    @Override
    protected void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView. onResume ()，实现地图生命周期管理
        mMapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView. onPause ()，实现地图生命周期管理
        mMapView.onPause();
    }
}
